Devcontainerを用いてPythonやAWS CDK・Serverless Frameworkなどのデプロイ環境の構築をしてみた
データアナリティクス事業本部のueharaです。
今回は、Devcontainerを用いてPythonやAWS CDK・Serverless Frameworkなどのデプロイ環境の構築をしてみたいと思います。
Devcontainerとは
Devcontainerは一言でいうとVSCodeの開発環境構築支援機能になります。
Dockerコンテナを開発環境として利用することで、開発やデプロイに必要なランタイムのバージョンやライブラリ、VSCodeの拡張機能をコンテナ内に包含させることができます。
ユーザはプロジェクトディレクトリを開く際にDevcontainerで起動をするだけで開発環境が準備されるので、案件に新しくアサインされるメンバーもすぐに開発・デプロイをすることができます。
今回作成する環境
今回は、私が普段案件に参画する際によく使う以下のランタイムやライブラリを含むDevcontainerを作成したいと思います。
- Python
- Node.js
- AWS CDK
- AWS SAM
- Serverless Framework
事前準備
VSCodeのインストールと、Devcontainerの拡張機能をインストールしておきます。
やってみた
ディレクトリ構成
まず、ディレクトリ構成ですが、今回はシンプルに以下のようにしてみました。
$ tree . -a
.
├── .devcontainer.json
├── Dockerfile
└── src
└── test.py
各ファイルの記述
早速ですが、 Dockerfile
は以下のように書いてみました。
# syntax=docker/dockerfile:1
FROM debian:bookworm-slim
# バージョンの指定
ARG PYTHON_VERSION=3.11
ARG NODEJS_VERSION=20.16.0
ARG AWS_CDK_VERSION=2.150.0
ARG SERVERLESS_VERSION=3.38.0
ARG AWS_SAM_VERSION=1.120.0
# ターゲットのアーキテクチャ
ARG TARGETARCH
# 環境変数の設定
ENV DEBIAN_FRONTEND=noninteractive
ENV PATH="/root/.local/bin:${PATH}"
# APTキャッシュの設定
RUN rm -f /etc/apt/apt.conf.d/docker-clean; \
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
# 基本的なシステムパッケージのインストール
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install --no-install-recommends -y \
curl \
gnupg \
lsb-release \
software-properties-common \
bash \
jq \
unzip \
git
# Pythonのインストール
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install --no-install-recommends -y \
python${PYTHON_VERSION} \
python3-pip \
python3-venv \
&& python3 -m venv /opt/venv
# 仮想環境を有効化
ENV PATH="/opt/venv/bin:$PATH"
# Node.jsのインストール
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
curl -fsSL https://deb.nodesource.com/setup_${NODEJS_VERSION%%.*}.x | bash - \
&& apt-get update \
&& apt-get install --no-install-recommends -y nodejs=${NODEJS_VERSION}-1nodesource1 \
&& npm install -g npm@latest
# AWS CLIのインストール
RUN case ${TARGETARCH} in \
"amd64") \
AWS_CLI_URL="https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" ;; \
"arm64") \
AWS_CLI_URL="https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" ;; \
*) \
echo "Unsupported architecture: ${TARGETARCH}" >&2; \
exit 1 ;; \
esac && \
curl "${AWS_CLI_URL}" -o "awscliv2.zip" && \
unzip awscliv2.zip && \
./aws/install && \
rm -rf aws awscliv2.zip
# AWS CDK, Typescript, AWS SAM, Serverless Frameworkのインストール
RUN --mount=type=cache,target=/root/.npm,sharing=locked \
--mount=type=cache,target=/root/.cache/pip,sharing=locked \
npm install -g typescript aws-cdk@${AWS_CDK_VERSION} serverless@${SERVERLESS_VERSION} \
&& pip3 install aws-sam-cli==${AWS_SAM_VERSION}
# 作業ディレクトリの設定
WORKDIR /workspace
# デフォルトのシェルをbashに設定
SHELL ["/bin/bash", "-c"]
# コンテナ起動時のデフォルトコマンド
CMD ["/bin/bash"]
ベースイメージはDebian Boockwormで、特に使用頻度の低いパッケージを除いたslim版を利用しています。
ランタイムやライブラリのバージョンは以下のように ARG
を用いて定義しています。
ARG PYTHON_VERSION=3.11
ARG NODEJS_VERSION=20.16.0
ARG AWS_CDK_VERSION=2.150.0
ARG SERVERLESS_VERSION=3.38.0
ARG AWS_SAM_VERSION=1.120.0
今回は開発環境の構築のためマルチステージビルドは利用していません。
apt-get
や pip
の実行時には RUN --mount=type=cache
というキャッシュディレクトリを指定する機能を利用しています。(Docker 18.09より統合されたBuildKitが必要になります)
指定されたディレクトリはビルドを跨いでデータを保持しておくことができ、かつディレクトリ内のファイルはレイヤーに含まれなくなりますので、イメージサイズが小さくなるというメリットがあります。
例えば apt-get
コマンドの実行時にはこれまではお作法的に apt-get clean
と rm -rf /var/lib/apt/lists/*
を実行してイメージサイズを小さくしていたと思いますが、上記の通り RUN --mount=type=cache
をするとレイヤーに含まれなくなるのでそれが不要になります。
※むしろ、キャッシュとしてビルドを跨いで利用したいので、 Dockerfile
内に以下の通りapt操作後に自動的にクリーンアップが実行されるのを防ぐ記載をしています。
# APTキャッシュの設定
RUN rm -f /etc/apt/apt.conf.d/docker-clean; \
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
次に、.devcontainer.json
は以下の通りです。
{
"name": "My DevContainer",
"build": {
"dockerfile": "Dockerfile"
},
"workspaceFolder": "/workspace",
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached",
"mounts": [
// AWSのプロファイルディレクトリをマウント
"source=${localEnv:HOME}/.aws,target=/root/.aws,type=bind,consistency=cached"
]
}
ビルドは先に作成した Dockerfile
を参照するようにしています。
ワークスペースのディレクトリはそのまま /workspace
です。
mounts
については、いまいまはAWSの認証情報のみを指定しています。
例えば npm install
を使用して node_modules
などマウントする必要のないファイルやディレクトリができる場合は名前付きボリュームで指定しておいた方が良いかと思いますが、ここでは省略しています。
test.py
は単に実行確認のため、以下にしています。
print("Hello World!")
Devcontainerの起動
作成したディレクトリをVSCodeで開きます。
すると、以下のように右下にコンテナで開くことをサジェストするポップアップが表示されます。
ここから起動しても良いのですが、コマンドパレットで Rebuild and Reopen in Container
を指定してビルドとコンテナの起動を実行してみます。
コンテナのビルドが完了すると、コンテナに接続されたVSCode(実際にはコンテナ内にもVSCodeが存在)が起動します。
冒頭で述べた通り拡張機能もローカルのVSCodeからは分離されているのですが、以下の図のボタンから一括でローカルの拡張機能をインストールすることもできます。
実行確認
Devcontainerが起動できたので、ランタイムやライブラリが期待通りにインストールされているか、ターミナルのタブからコマンドを叩いて確認してみます。
期待通りインストールできていることが確認できました。
test.py
もテストのため実行してみます。
こちらも問題なく実行できました。
最後に
今回は、Devcontainerを用いてPythonやAWS CDK・Serverless Frameworkなどのデプロイ環境の構築をしてみました。
参考になりましたら幸いです。